@gpc-cli/core 0.10.8 → 0.11.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +9 -1
- package/dist/index.js +178 -9
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1368,6 +1368,8 @@ interface ParsedManifest {
|
|
|
1368
1368
|
services: ManifestComponent[];
|
|
1369
1369
|
receivers: ManifestComponent[];
|
|
1370
1370
|
providers: ManifestComponent[];
|
|
1371
|
+
/** `<meta-data>` entries of `<application>`, name to value. Entries without a value are omitted. */
|
|
1372
|
+
metaData: Record<string, string>;
|
|
1371
1373
|
/** Android 16+ compat shim for non-16KB-aligned native libs. */
|
|
1372
1374
|
pageSizeCompat?: boolean;
|
|
1373
1375
|
/** Set when the manifest could not be fully parsed -- manifest-dependent scanners should skip. */
|
|
@@ -1668,6 +1670,12 @@ declare function runWatchLoop(opts: WatchOptions): Promise<void>;
|
|
|
1668
1670
|
/** Returns true if breach state changed (breach started or cleared). */
|
|
1669
1671
|
declare function trackBreachState(packageName: string, isBreaching: boolean): Promise<boolean>;
|
|
1670
1672
|
declare function sendNotification(title: string, body: string): void;
|
|
1673
|
+
/**
|
|
1674
|
+
* Re-rates a saved status against the thresholds of the current run. A cached
|
|
1675
|
+
* status keeps the thresholds of the run that fetched it, so serving it as-is
|
|
1676
|
+
* would gate on values the caller never asked for.
|
|
1677
|
+
*/
|
|
1678
|
+
declare function applyVitalThresholds(status: AppStatus, vitalThresholds: GetAppStatusOptions["vitalThresholds"]): AppStatus;
|
|
1671
1679
|
declare function statusHasBreach(status: AppStatus): boolean;
|
|
1672
1680
|
|
|
1673
1681
|
interface ChangelogEntry {
|
|
@@ -2052,4 +2060,4 @@ declare function readinessBadgeColor(grade: ReadinessGrade): string;
|
|
|
2052
2060
|
declare function readinessBadgeUrl(score: ReadinessScore): string;
|
|
2053
2061
|
declare function readinessBadgeMarkdown(score: ReadinessScore): string;
|
|
2054
2062
|
|
|
2055
|
-
export { ApiError, type ApiSigningFingerprint, type AppInfo, type AppStatus, type ApplyReleaseNotesResult, type AuditEntry, type BatchSyncResult, type BundleAnalysis, type BundleComparison, type BundleEntry, type BundleSizeCheckResult, type BundleSizeConfig, type BundlesWaitOptions, type ChangelogEntry, type ChecklistInput, type ChecklistItem, type ChecklistResult, type CommandContext, type CommitCluster, type CommitResult, ConfigError, type CreateEnterpriseAppParams, DEFAULT_LIMITS, DEFAULT_MODELS, DEFAULT_PREFLIGHT_CONFIG, DEFAULT_WATCH_THRESHOLDS, type DecodedNotification, type DiffToken, type DiscoverPluginsOptions, type DiscoveredPlugin, type DryRunPublishResult, type DryRunResult, type DryRunUploadResult, type ErrorReason, type ExportImagesOptions, type ExportImagesSummary, type ExternalTransactionRefundOptions, type FastlaneDetection, type FastlaneLane, type FetchChangelogOptions, type FieldLintResult, type FileValidationResult, type FinancialReportDownload, type FindingSeverity, GOOGLE_PLAY_LANGUAGES, type GameConfigDiff, type GamesPushOptions, type GamesSyncResult, type GenerateOptions, type GeneratedChangelog, type GetAppStatusOptions, type GitNotesOptions, type GitReleaseNotes, type GitRunner, GpcError, type ImageSyncDetail, type ImageSyncOptions, type ImageSyncResult, type ImageValidationResult, type InitOptions, type InitResult, type InternalSharingUploadResult, type KeystoreFingerprint, type ListGamesConfigOptions, type ListIapOptions, type ListReportsResult, type ListSubscriptionsOptions, type ListUsersOptions, type ListVoidedOptions, type ListingDiff, type ListingFieldLimits, type ListingLintResult, type ListingsResult, type LoadedPlugin, type LocaleBundle, type LocaleEntry, type MigrationResult, NetworkError, type OneTimeProductDiff, type OutputMode, PERMISSION_PROPAGATION_WARNING, PLACEHOLDER_TEXT, PLAY_STORE_LIMIT, PROVIDER_WHITELIST, type ParsedCommit, type ParsedManifest, type ParsedMonth, type PlayStoreFormat, type PlayStoreRenderOptions, PluginManager, type PreflightConfig, type PreflightFinding, type PreflightOptions, type PreflightResult, type PreflightScanner, type Provider, type PublishOptions, type PublishResult, type PushResult, type QuotaUsage, RENDERERS, REVIEW_SORT_PRESETS, type RawCommit, type ReadinessBreakdownEntry, type ReadinessGrade, type ReadinessScore, type ReadinessSignal, type ReadinessSignalStatus, type RefundReviewPreference, type ReleaseDiff, type ReleaseNotesValidation, type ReleaseStatusResult, type Renderer, type ReportObject, type ReportsAuth, type ResolveAiConfigOptions, type ResolveLocalesOptions, type ReviewAnalysis, type ReviewExportOptions, type ReviewOrderRefundOptions, type ReviewOrderRefundResult, type ReviewSortPreset, type ReviewsFilterOptions, type RevocationRefundType, type RtdnStatus, SECTION_ORDER, SENSITIVE_ARG_KEYS, SENSITIVE_KEYS, SEVERITY_ORDER, type ScaffoldOptions, type ScaffoldResult, type SigningConsistencyResult, type SigningKeyComparison, type Spinner, type StatsReportDownload, type StatusDiff, type StatusRelease, type StatusReviews, type StatusVitalMetric, type SubscriptionAnalytics, type SubscriptionDiff, type SyncResult, type ThresholdResult, type TrainConfig, type TrainState, type TranslateBundleOptions, type TranslatedBundle, type TranslationFailure, type TranslationPath, type TranslationResult, type Translator, type TranslatorConfig, type UploadResult, VALID_WATCH_METRICS, type ValidateCheck, type ValidateOptions, type ValidateResult, type ValidatedPluginApproval, type VersionVitalsComparison, type VersionVitalsRow, type VitalsOverview, type VitalsQueryOptions, type VitalsTrendComparison, type WatchAction, type WatchCallbacks, type WatchConfig, type WatchEvent, type WatchMetric, type WatchOptions, type WatchRollout, type WatchSummary, type WatchVitalReading, type WatchVitalsOptions, type WebhookPayload, type ZipCsvEntry, abortTrain, acknowledgeProductPurchase, activateBasePlan, activateOffer, addRecoveryTargeting, addTesters, advanceTrain, analyzeBundle, analyzeRemoteListings, analyzeReviews, annotateListResult, applyReleaseNotes, assertRateThreshold, assignRelease, batchGetOrders, batchSyncInAppProducts, buildChecklist, buildExternalTransactionRefund, buildLocaleBundle, bundleToReleaseNotes, cancelRecoveryAction, cancelSubscriptionPurchase, cancelSubscriptionV2, checkBundleSize, checkSigningConsistency, checkThreshold, classifyError, clearAuditLog, commitWithRescue, compareBundles, compareFingerprints, compareVersionVitals, compareVitalsTrend, computeStatusDiff, consumeProductPurchase, convertRegionPrices, createAchievementConfig, createAuditEntry, createDeviceTier, createEnterpriseApp, createExternalTransaction, createGrant, createInAppProduct, createLeaderboardConfig, createOffer, createOneTimeOffer, createOneTimeProduct, createRecoveryAction, createSpinner, createSubscription, createTrack, createTranslator, deactivateBasePlan, deactivateOffer, decodeCsvText, decodeNotification, decodeStatsCsv, defaultGitRunner, deferSubscriptionPurchase, deferSubscriptionV2, deleteAchievementConfig, deleteBasePlan, deleteGrant, deleteImage, deleteInAppProduct, deleteLeaderboardConfig, deleteListing, deleteOffer, deleteOneTimeOffer, deleteOneTimeProduct, deleteSubscription, deployRecoveryAction, detectFastlane, detectOutputFormat, diffAchievementConfig, diffLeaderboardConfig, diffListings, diffListingsCommand, diffListingsEnhanced, diffOneTimeProduct, diffReleases, diffSubscription, discoverPluginEntries, discoverPlugins, dispatchWebhook, downloadFinancialReport, downloadGeneratedApk, downloadReportObject, downloadStatsReport, exportImages, exportReviews, extractCsvEntriesFromZip, fetchAggregateCost, fetchChangelog, fetchReleaseNotes, findBundle, formatChangelogEntry, formatCustomPayload, formatDiscordPayload, formatJunit, formatMoney, formatNotification, formatOutput, formatPathLabel, formatSlackPayload, formatStatusDiff, formatStatusSummary, formatStatusTable, formatWordDiff, generateChangelog, generateMigrationPlan, generateNotesFromGit, getAchievementConfig, getAllScannerNames, getApiSigningFingerprint, getAppInfo, getAppStatus, getCountryAvailability, getDeviceTier, getExternalTransaction, getInAppProduct, getKeystoreFingerprint, getLeaderboardConfig, getListings, getOffer, getOneTimeOffer, getOneTimeProduct, getOrderDetails, getProductPurchase, getProductPurchaseV2, getQuotaUsage, getReleasesStatus, getReview, getRtdnStatus, getSubscription, getSubscriptionAnalytics, getSubscriptionPurchase, getTrainStatus, getUser, getVitalsAnomalies, getVitalsAnr, getVitalsBattery, getVitalsCrashes, getVitalsErrorCount, getVitalsLmk, getVitalsMemory, getVitalsMemoryBitmap, getVitalsMemoryRss, getVitalsOverview, getVitalsRendering, getVitalsStartup, gradeFromPercent, gunzipIfNeeded, handleBreach, importDataSafety, importTestersFromCsv, initAudit, initProject, inviteUser, isFinancialReportType, isGzip, isStatsReportType, isValidBcp47, isValidReportType, isValidStatsDimension, isVersionedNotesDir, isZip, latestWorstValue, lintListing, lintListings, lintLocalListings, listAchievementConfigs, listAchievements, listAuditEvents, listBundles, listDeviceTiers, listGeneratedApks, listGrants, listImages, listInAppProducts, listLeaderboardConfigs, listLeaderboards, listOffers, listOneTimeOffers, listOneTimeProducts, listRecoveryActions, listReportObjects, listReports, listReviews, listSubscriptions, listTesters, listTracks, listUsers, listVoidedPurchases, loadPreflightConfig, loadStatusCache, maybePaginate, migratePrices, monthToken, moreResultsFooter, normalizeFingerprint, parseAppfile, parseCommit, parseFastfile, parseGrantArg, parseKeytoolOutput, parseMonth, parseRemoteUrl, pauseTrain, promoteRelease, publish, publishEnterpriseApp, pullAchievementConfigs, pullLeaderboardConfigs, pullListings, pushAchievementConfigs, pushLeaderboardConfigs, pushListings, readListingsFromDir, readMetricValue, readReleaseNotesForVersion, readReleaseNotesFromDir, readinessBadgeColor, readinessBadgeMarkdown, readinessBadgeUrl, redactAuditArgs, redactSensitive, refundExternalTransaction, refundOrder, relativeTime, removeTesters, removeUser, renderChecklistMarkdown, renderJson, renderMarkdown, renderPlayStore, renderPlayStoreJson, renderPlayStoreMd, renderPlayStorePrompt, renderPrompt, replyToReview, reportAccessDeniedError, reportBucketNotFoundError, reportObjectNotFoundError, reportPrefix, resolveAiConfig, resolveLocales, resolveReportsBucket, retryOnUploadNotComplete, reviewOrderRefund, revokeSubscriptionPurchase, runPreflight, runWatch, runWatchLoop, safePath, safePathWithin, saveStatusCache, scaffoldPlugin, scoreReadiness, searchAuditEvents, searchVitalsErrors, sendNotification, sendWebhook, setAchievementIcon, setLeaderboardIcon, sha256File, sortResults, sortReviews, startTrain, statusHasBreach, syncImages, syncInAppProducts, topFiles, trackBreachState, translateBundle, updateAchievementConfig, updateAppDetails, updateDataSafety, updateGrant, updateInAppProduct, updateLeaderboardConfig, updateListing, updateOffer, updateOneTimeOffer, updateOneTimeProduct, updateRollout, updateSubscription, updateTrackConfig, updateUser, uploadExternallyHosted, uploadImage, uploadInternalSharing, uploadRelease, validateAndCommit, validateBundleForApply, validateImage, validateLanguageCode, validatePackageName, validatePluginForApproval, validatePreSubmission, validateReleaseNotes, validateSku, validateTrackName, validateUploadFile, validateVersionCode, waitForBundle, waitForBundleProcessing, watchVitalsWithAutoHalt, wordDiff, worstSliceAverage, writeAuditLog, writeListingsToDir, writeMigrationOutput };
|
|
2063
|
+
export { ApiError, type ApiSigningFingerprint, type AppInfo, type AppStatus, type ApplyReleaseNotesResult, type AuditEntry, type BatchSyncResult, type BundleAnalysis, type BundleComparison, type BundleEntry, type BundleSizeCheckResult, type BundleSizeConfig, type BundlesWaitOptions, type ChangelogEntry, type ChecklistInput, type ChecklistItem, type ChecklistResult, type CommandContext, type CommitCluster, type CommitResult, ConfigError, type CreateEnterpriseAppParams, DEFAULT_LIMITS, DEFAULT_MODELS, DEFAULT_PREFLIGHT_CONFIG, DEFAULT_WATCH_THRESHOLDS, type DecodedNotification, type DiffToken, type DiscoverPluginsOptions, type DiscoveredPlugin, type DryRunPublishResult, type DryRunResult, type DryRunUploadResult, type ErrorReason, type ExportImagesOptions, type ExportImagesSummary, type ExternalTransactionRefundOptions, type FastlaneDetection, type FastlaneLane, type FetchChangelogOptions, type FieldLintResult, type FileValidationResult, type FinancialReportDownload, type FindingSeverity, GOOGLE_PLAY_LANGUAGES, type GameConfigDiff, type GamesPushOptions, type GamesSyncResult, type GenerateOptions, type GeneratedChangelog, type GetAppStatusOptions, type GitNotesOptions, type GitReleaseNotes, type GitRunner, GpcError, type ImageSyncDetail, type ImageSyncOptions, type ImageSyncResult, type ImageValidationResult, type InitOptions, type InitResult, type InternalSharingUploadResult, type KeystoreFingerprint, type ListGamesConfigOptions, type ListIapOptions, type ListReportsResult, type ListSubscriptionsOptions, type ListUsersOptions, type ListVoidedOptions, type ListingDiff, type ListingFieldLimits, type ListingLintResult, type ListingsResult, type LoadedPlugin, type LocaleBundle, type LocaleEntry, type MigrationResult, NetworkError, type OneTimeProductDiff, type OutputMode, PERMISSION_PROPAGATION_WARNING, PLACEHOLDER_TEXT, PLAY_STORE_LIMIT, PROVIDER_WHITELIST, type ParsedCommit, type ParsedManifest, type ParsedMonth, type PlayStoreFormat, type PlayStoreRenderOptions, PluginManager, type PreflightConfig, type PreflightFinding, type PreflightOptions, type PreflightResult, type PreflightScanner, type Provider, type PublishOptions, type PublishResult, type PushResult, type QuotaUsage, RENDERERS, REVIEW_SORT_PRESETS, type RawCommit, type ReadinessBreakdownEntry, type ReadinessGrade, type ReadinessScore, type ReadinessSignal, type ReadinessSignalStatus, type RefundReviewPreference, type ReleaseDiff, type ReleaseNotesValidation, type ReleaseStatusResult, type Renderer, type ReportObject, type ReportsAuth, type ResolveAiConfigOptions, type ResolveLocalesOptions, type ReviewAnalysis, type ReviewExportOptions, type ReviewOrderRefundOptions, type ReviewOrderRefundResult, type ReviewSortPreset, type ReviewsFilterOptions, type RevocationRefundType, type RtdnStatus, SECTION_ORDER, SENSITIVE_ARG_KEYS, SENSITIVE_KEYS, SEVERITY_ORDER, type ScaffoldOptions, type ScaffoldResult, type SigningConsistencyResult, type SigningKeyComparison, type Spinner, type StatsReportDownload, type StatusDiff, type StatusRelease, type StatusReviews, type StatusVitalMetric, type SubscriptionAnalytics, type SubscriptionDiff, type SyncResult, type ThresholdResult, type TrainConfig, type TrainState, type TranslateBundleOptions, type TranslatedBundle, type TranslationFailure, type TranslationPath, type TranslationResult, type Translator, type TranslatorConfig, type UploadResult, VALID_WATCH_METRICS, type ValidateCheck, type ValidateOptions, type ValidateResult, type ValidatedPluginApproval, type VersionVitalsComparison, type VersionVitalsRow, type VitalsOverview, type VitalsQueryOptions, type VitalsTrendComparison, type WatchAction, type WatchCallbacks, type WatchConfig, type WatchEvent, type WatchMetric, type WatchOptions, type WatchRollout, type WatchSummary, type WatchVitalReading, type WatchVitalsOptions, type WebhookPayload, type ZipCsvEntry, abortTrain, acknowledgeProductPurchase, activateBasePlan, activateOffer, addRecoveryTargeting, addTesters, advanceTrain, analyzeBundle, analyzeRemoteListings, analyzeReviews, annotateListResult, applyReleaseNotes, applyVitalThresholds, assertRateThreshold, assignRelease, batchGetOrders, batchSyncInAppProducts, buildChecklist, buildExternalTransactionRefund, buildLocaleBundle, bundleToReleaseNotes, cancelRecoveryAction, cancelSubscriptionPurchase, cancelSubscriptionV2, checkBundleSize, checkSigningConsistency, checkThreshold, classifyError, clearAuditLog, commitWithRescue, compareBundles, compareFingerprints, compareVersionVitals, compareVitalsTrend, computeStatusDiff, consumeProductPurchase, convertRegionPrices, createAchievementConfig, createAuditEntry, createDeviceTier, createEnterpriseApp, createExternalTransaction, createGrant, createInAppProduct, createLeaderboardConfig, createOffer, createOneTimeOffer, createOneTimeProduct, createRecoveryAction, createSpinner, createSubscription, createTrack, createTranslator, deactivateBasePlan, deactivateOffer, decodeCsvText, decodeNotification, decodeStatsCsv, defaultGitRunner, deferSubscriptionPurchase, deferSubscriptionV2, deleteAchievementConfig, deleteBasePlan, deleteGrant, deleteImage, deleteInAppProduct, deleteLeaderboardConfig, deleteListing, deleteOffer, deleteOneTimeOffer, deleteOneTimeProduct, deleteSubscription, deployRecoveryAction, detectFastlane, detectOutputFormat, diffAchievementConfig, diffLeaderboardConfig, diffListings, diffListingsCommand, diffListingsEnhanced, diffOneTimeProduct, diffReleases, diffSubscription, discoverPluginEntries, discoverPlugins, dispatchWebhook, downloadFinancialReport, downloadGeneratedApk, downloadReportObject, downloadStatsReport, exportImages, exportReviews, extractCsvEntriesFromZip, fetchAggregateCost, fetchChangelog, fetchReleaseNotes, findBundle, formatChangelogEntry, formatCustomPayload, formatDiscordPayload, formatJunit, formatMoney, formatNotification, formatOutput, formatPathLabel, formatSlackPayload, formatStatusDiff, formatStatusSummary, formatStatusTable, formatWordDiff, generateChangelog, generateMigrationPlan, generateNotesFromGit, getAchievementConfig, getAllScannerNames, getApiSigningFingerprint, getAppInfo, getAppStatus, getCountryAvailability, getDeviceTier, getExternalTransaction, getInAppProduct, getKeystoreFingerprint, getLeaderboardConfig, getListings, getOffer, getOneTimeOffer, getOneTimeProduct, getOrderDetails, getProductPurchase, getProductPurchaseV2, getQuotaUsage, getReleasesStatus, getReview, getRtdnStatus, getSubscription, getSubscriptionAnalytics, getSubscriptionPurchase, getTrainStatus, getUser, getVitalsAnomalies, getVitalsAnr, getVitalsBattery, getVitalsCrashes, getVitalsErrorCount, getVitalsLmk, getVitalsMemory, getVitalsMemoryBitmap, getVitalsMemoryRss, getVitalsOverview, getVitalsRendering, getVitalsStartup, gradeFromPercent, gunzipIfNeeded, handleBreach, importDataSafety, importTestersFromCsv, initAudit, initProject, inviteUser, isFinancialReportType, isGzip, isStatsReportType, isValidBcp47, isValidReportType, isValidStatsDimension, isVersionedNotesDir, isZip, latestWorstValue, lintListing, lintListings, lintLocalListings, listAchievementConfigs, listAchievements, listAuditEvents, listBundles, listDeviceTiers, listGeneratedApks, listGrants, listImages, listInAppProducts, listLeaderboardConfigs, listLeaderboards, listOffers, listOneTimeOffers, listOneTimeProducts, listRecoveryActions, listReportObjects, listReports, listReviews, listSubscriptions, listTesters, listTracks, listUsers, listVoidedPurchases, loadPreflightConfig, loadStatusCache, maybePaginate, migratePrices, monthToken, moreResultsFooter, normalizeFingerprint, parseAppfile, parseCommit, parseFastfile, parseGrantArg, parseKeytoolOutput, parseMonth, parseRemoteUrl, pauseTrain, promoteRelease, publish, publishEnterpriseApp, pullAchievementConfigs, pullLeaderboardConfigs, pullListings, pushAchievementConfigs, pushLeaderboardConfigs, pushListings, readListingsFromDir, readMetricValue, readReleaseNotesForVersion, readReleaseNotesFromDir, readinessBadgeColor, readinessBadgeMarkdown, readinessBadgeUrl, redactAuditArgs, redactSensitive, refundExternalTransaction, refundOrder, relativeTime, removeTesters, removeUser, renderChecklistMarkdown, renderJson, renderMarkdown, renderPlayStore, renderPlayStoreJson, renderPlayStoreMd, renderPlayStorePrompt, renderPrompt, replyToReview, reportAccessDeniedError, reportBucketNotFoundError, reportObjectNotFoundError, reportPrefix, resolveAiConfig, resolveLocales, resolveReportsBucket, retryOnUploadNotComplete, reviewOrderRefund, revokeSubscriptionPurchase, runPreflight, runWatch, runWatchLoop, safePath, safePathWithin, saveStatusCache, scaffoldPlugin, scoreReadiness, searchAuditEvents, searchVitalsErrors, sendNotification, sendWebhook, setAchievementIcon, setLeaderboardIcon, sha256File, sortResults, sortReviews, startTrain, statusHasBreach, syncImages, syncInAppProducts, topFiles, trackBreachState, translateBundle, updateAchievementConfig, updateAppDetails, updateDataSafety, updateGrant, updateInAppProduct, updateLeaderboardConfig, updateListing, updateOffer, updateOneTimeOffer, updateOneTimeProduct, updateRollout, updateSubscription, updateTrackConfig, updateUser, uploadExternallyHosted, uploadImage, uploadInternalSharing, uploadRelease, validateAndCommit, validateBundleForApply, validateImage, validateLanguageCode, validatePackageName, validatePluginForApproval, validatePreSubmission, validateReleaseNotes, validateSku, validateTrackName, validateUploadFile, validateVersionCode, waitForBundle, waitForBundleProcessing, watchVitalsWithAutoHalt, wordDiff, worstSliceAverage, writeAuditLog, writeListingsToDir, writeMigrationOutput };
|
package/dist/index.js
CHANGED
|
@@ -3093,7 +3093,7 @@ async function loadStatusCache(packageName, ttlSeconds = DEFAULT_TTL_SECONDS) {
|
|
|
3093
3093
|
const raw = await readFile4(cacheFilePath(packageName), "utf-8");
|
|
3094
3094
|
const entry = JSON.parse(raw);
|
|
3095
3095
|
const age = (Date.now() - new Date(entry.fetchedAt).getTime()) / 1e3;
|
|
3096
|
-
if (age >
|
|
3096
|
+
if (age > ttlSeconds) return null;
|
|
3097
3097
|
const data = entry.data;
|
|
3098
3098
|
return {
|
|
3099
3099
|
...data,
|
|
@@ -3164,6 +3164,14 @@ async function queryVitalWithTrend(reporting, packageName, metricSet, days) {
|
|
|
3164
3164
|
return { current, previous, trend };
|
|
3165
3165
|
}
|
|
3166
3166
|
var SKIPPED_VITAL = { current: void 0, previous: void 0, trend: null };
|
|
3167
|
+
function resolveStatusThresholds(overrides) {
|
|
3168
|
+
return {
|
|
3169
|
+
crashRate: overrides?.crashRate ?? DEFAULT_THRESHOLDS.crashRate,
|
|
3170
|
+
anrRate: overrides?.anrRate ?? DEFAULT_THRESHOLDS.anrRate,
|
|
3171
|
+
slowStartRate: overrides?.slowStartRate ?? DEFAULT_THRESHOLDS.slowStartRate,
|
|
3172
|
+
slowRenderingRate: overrides?.slowRenderingRate ?? DEFAULT_THRESHOLDS.slowRenderingRate
|
|
3173
|
+
};
|
|
3174
|
+
}
|
|
3167
3175
|
function toVitalMetric(value, threshold, previousValue, trend) {
|
|
3168
3176
|
const base = previousValue !== void 0 ? { value, threshold, status: "unknown", previousValue, trend: trend ?? null } : { value, threshold, status: "unknown" };
|
|
3169
3177
|
if (value === void 0) return { ...base, status: "unknown" };
|
|
@@ -3210,12 +3218,7 @@ async function getAppStatus(client, reporting, packageName, options = {}) {
|
|
|
3210
3218
|
const days = options.days ?? 7;
|
|
3211
3219
|
const reviewDays = options.reviewDays ?? 30;
|
|
3212
3220
|
const sections = new Set(options.sections ?? ["releases", "vitals", "reviews"]);
|
|
3213
|
-
const thresholds =
|
|
3214
|
-
crashRate: options.vitalThresholds?.crashRate ?? DEFAULT_THRESHOLDS.crashRate,
|
|
3215
|
-
anrRate: options.vitalThresholds?.anrRate ?? DEFAULT_THRESHOLDS.anrRate,
|
|
3216
|
-
slowStartRate: options.vitalThresholds?.slowStartRate ?? DEFAULT_THRESHOLDS.slowStartRate,
|
|
3217
|
-
slowRenderingRate: options.vitalThresholds?.slowRenderingRate ?? DEFAULT_THRESHOLDS.slowRenderingRate
|
|
3218
|
-
};
|
|
3221
|
+
const thresholds = resolveStatusThresholds(options.vitalThresholds);
|
|
3219
3222
|
const [
|
|
3220
3223
|
releasesResult,
|
|
3221
3224
|
crashesResult,
|
|
@@ -3592,6 +3595,22 @@ function sendNotification(title, body) {
|
|
|
3592
3595
|
} catch {
|
|
3593
3596
|
}
|
|
3594
3597
|
}
|
|
3598
|
+
function applyVitalThresholds(status, vitalThresholds) {
|
|
3599
|
+
const v = status.vitals;
|
|
3600
|
+
if (!v) return status;
|
|
3601
|
+
const t = resolveStatusThresholds(vitalThresholds);
|
|
3602
|
+
const rate = (metric, threshold) => metric && toVitalMetric(metric.value, threshold, metric.previousValue, metric.trend);
|
|
3603
|
+
return {
|
|
3604
|
+
...status,
|
|
3605
|
+
vitals: {
|
|
3606
|
+
...v,
|
|
3607
|
+
crashes: rate(v.crashes, t.crashRate),
|
|
3608
|
+
anr: rate(v.anr, t.anrRate),
|
|
3609
|
+
slowStarts: rate(v.slowStarts, t.slowStartRate),
|
|
3610
|
+
slowRender: rate(v.slowRender, t.slowRenderingRate)
|
|
3611
|
+
}
|
|
3612
|
+
};
|
|
3613
|
+
}
|
|
3595
3614
|
function statusHasBreach(status) {
|
|
3596
3615
|
return status.vitals.crashes.status === "breach" || status.vitals.anr.status === "breach" || status.vitals.slowStarts.status === "breach" || status.vitals.slowRender.status === "breach";
|
|
3597
3616
|
}
|
|
@@ -6285,6 +6304,7 @@ var RESOURCE_IDS = {
|
|
|
6285
6304
|
16843376: "targetSdkVersion",
|
|
6286
6305
|
16842782: "debuggable",
|
|
6287
6306
|
16842786: "permission",
|
|
6307
|
+
16842788: "value",
|
|
6288
6308
|
16842795: "exported",
|
|
6289
6309
|
16843378: "testOnly",
|
|
6290
6310
|
16843760: "usesCleartextTraffic",
|
|
@@ -6413,6 +6433,7 @@ function extractManifestData(manifest) {
|
|
|
6413
6433
|
const services = app ? extractComponents(app, "service") : [];
|
|
6414
6434
|
const receivers = app ? extractComponents(app, "receiver") : [];
|
|
6415
6435
|
const providers = app ? extractComponents(app, "provider") : [];
|
|
6436
|
+
const metaData = app ? extractMetaData(app) : {};
|
|
6416
6437
|
return {
|
|
6417
6438
|
packageName,
|
|
6418
6439
|
versionCode,
|
|
@@ -6429,9 +6450,20 @@ function extractManifestData(manifest) {
|
|
|
6429
6450
|
activities,
|
|
6430
6451
|
services,
|
|
6431
6452
|
receivers,
|
|
6432
|
-
providers
|
|
6453
|
+
providers,
|
|
6454
|
+
metaData
|
|
6433
6455
|
};
|
|
6434
6456
|
}
|
|
6457
|
+
function extractMetaData(elem) {
|
|
6458
|
+
const entries = {};
|
|
6459
|
+
for (const el of getChildren(elem, "meta-data")) {
|
|
6460
|
+
const attrs = el.attribute || [];
|
|
6461
|
+
const name = getAttrByName(attrs, "name");
|
|
6462
|
+
const value = getAttrByName(attrs, "value");
|
|
6463
|
+
if (name && value !== void 0) entries[name] = value;
|
|
6464
|
+
}
|
|
6465
|
+
return entries;
|
|
6466
|
+
}
|
|
6435
6467
|
function extractComponents(appElement, tagName) {
|
|
6436
6468
|
return getChildren(appElement, tagName).map((el) => {
|
|
6437
6469
|
const compAttrs = el.attribute || [];
|
|
@@ -6534,7 +6566,8 @@ function createFallbackManifest() {
|
|
|
6534
6566
|
activities: [],
|
|
6535
6567
|
services: [],
|
|
6536
6568
|
receivers: [],
|
|
6537
|
-
providers: []
|
|
6569
|
+
providers: [],
|
|
6570
|
+
metaData: {}
|
|
6538
6571
|
};
|
|
6539
6572
|
}
|
|
6540
6573
|
function openAndScan(buffer, manifestPath = AAB_MANIFEST_PATH) {
|
|
@@ -7814,6 +7847,129 @@ var privacyScanner = {
|
|
|
7814
7847
|
}
|
|
7815
7848
|
};
|
|
7816
7849
|
|
|
7850
|
+
// src/preflight/billing-library.ts
|
|
7851
|
+
var BILLING_LIBRARY_DEADLINES = {
|
|
7852
|
+
5: { updateDeadline: "2024-08-31", extensionDeadline: "2024-11-01" },
|
|
7853
|
+
6: { updateDeadline: "2025-08-31", extensionDeadline: "2025-11-01" },
|
|
7854
|
+
7: { updateDeadline: "2026-08-31", extensionDeadline: "2026-11-01" },
|
|
7855
|
+
8: { updateDeadline: "2027-08-31", extensionDeadline: "2027-11-01" },
|
|
7856
|
+
9: { updateDeadline: "2028-08-31", extensionDeadline: "2028-11-01" }
|
|
7857
|
+
};
|
|
7858
|
+
var BILLING_PERMISSION = "com.android.vending.BILLING";
|
|
7859
|
+
var VERSION_META_DATA = "com.google.android.play.billingclient.version";
|
|
7860
|
+
var DEPRECATION_FAQ = "https://developer.android.com/google/play/billing/deprecation-faq";
|
|
7861
|
+
var RELEASE_NOTES = "https://developer.android.com/google/play/billing/release-notes";
|
|
7862
|
+
var MIGRATION_GUIDES = {
|
|
7863
|
+
8: "https://developer.android.com/google/play/billing/migrate-gpblv8",
|
|
7864
|
+
9: "https://developer.android.com/google/play/billing/migrate-gpblv9"
|
|
7865
|
+
};
|
|
7866
|
+
var KNOWN_MAJORS = Object.keys(BILLING_LIBRARY_DEADLINES).map(Number).sort((a, b) => a - b);
|
|
7867
|
+
var OLDEST_KNOWN = KNOWN_MAJORS[0] ?? 0;
|
|
7868
|
+
var NEWEST_KNOWN = KNOWN_MAJORS[KNOWN_MAJORS.length - 1] ?? 0;
|
|
7869
|
+
var ISO_DAY_RE = /^(\d{4})-(\d{2})-(\d{2})$/;
|
|
7870
|
+
function utcDayStart(isoDay, { years = 0, days = 0 } = {}) {
|
|
7871
|
+
const match = ISO_DAY_RE.exec(isoDay);
|
|
7872
|
+
if (!match) throw new Error(`Invalid Billing Library deadline "${isoDay}" (expected YYYY-MM-DD)`);
|
|
7873
|
+
return Date.UTC(Number(match[1]) + years, Number(match[2]) - 1, Number(match[3]) + days);
|
|
7874
|
+
}
|
|
7875
|
+
var BOUNDARIES = new Map(
|
|
7876
|
+
Object.entries(BILLING_LIBRARY_DEADLINES).map(([key, { updateDeadline, extensionDeadline }]) => {
|
|
7877
|
+
const major = Number(key);
|
|
7878
|
+
return [
|
|
7879
|
+
major,
|
|
7880
|
+
{
|
|
7881
|
+
infoFrom: utcDayStart(updateDeadline, { years: -1 }),
|
|
7882
|
+
updatePastFrom: utcDayStart(updateDeadline, { days: 1 }),
|
|
7883
|
+
extensionPastFrom: utcDayStart(extensionDeadline, { days: 1 })
|
|
7884
|
+
}
|
|
7885
|
+
];
|
|
7886
|
+
})
|
|
7887
|
+
);
|
|
7888
|
+
var STATUS_SEVERITY = {
|
|
7889
|
+
"older-than-table": "error",
|
|
7890
|
+
"past-extension-deadline": "error",
|
|
7891
|
+
"past-update-deadline": "warning",
|
|
7892
|
+
"update-deadline-within-a-year": "info"
|
|
7893
|
+
};
|
|
7894
|
+
function billingLibraryStatus(major, now) {
|
|
7895
|
+
if (major < OLDEST_KNOWN) return "older-than-table";
|
|
7896
|
+
const bounds = BOUNDARIES.get(major);
|
|
7897
|
+
if (!bounds) return void 0;
|
|
7898
|
+
const t = now.getTime();
|
|
7899
|
+
if (t >= bounds.extensionPastFrom) return "past-extension-deadline";
|
|
7900
|
+
if (t >= bounds.updatePastFrom) return "past-update-deadline";
|
|
7901
|
+
if (t >= bounds.infoFrom) return "update-deadline-within-a-year";
|
|
7902
|
+
return void 0;
|
|
7903
|
+
}
|
|
7904
|
+
function targetMajor(major, now) {
|
|
7905
|
+
const next = KNOWN_MAJORS.find((m) => {
|
|
7906
|
+
const bounds = BOUNDARIES.get(m);
|
|
7907
|
+
return m > major && bounds !== void 0 && now.getTime() < bounds.updatePastFrom;
|
|
7908
|
+
});
|
|
7909
|
+
return next ?? NEWEST_KNOWN + 1;
|
|
7910
|
+
}
|
|
7911
|
+
function migrationAdvice(target) {
|
|
7912
|
+
const guide = MIGRATION_GUIDES[target];
|
|
7913
|
+
return guide ? `Move to Billing Library ${target} or later. Migration guide: ${guide}` : `Move to Billing Library ${target} or later. Release notes: ${RELEASE_NOTES}`;
|
|
7914
|
+
}
|
|
7915
|
+
function billingLibraryFindings(manifest, now) {
|
|
7916
|
+
if (!manifest.permissions.includes(BILLING_PERMISSION)) return [];
|
|
7917
|
+
const version = manifest.metaData[VERSION_META_DATA];
|
|
7918
|
+
const majorMatch = version?.trim().match(/^\d+/);
|
|
7919
|
+
if (!version || !majorMatch) {
|
|
7920
|
+
const found = version ? `has an unreadable value ("${version}")` : "is missing";
|
|
7921
|
+
return [
|
|
7922
|
+
{
|
|
7923
|
+
scanner: "policy",
|
|
7924
|
+
ruleId: "billing-library-version-unknown",
|
|
7925
|
+
severity: "info",
|
|
7926
|
+
title: "Google Play Billing Library version could not be determined",
|
|
7927
|
+
message: `This bundle requests ${BILLING_PERMISSION}, but the ${VERSION_META_DATA} manifest entry ${found}. Manifest merging can remove it (for example a tools:node="remove" override), so preflight cannot compare the Billing Library version with Google Play's deadlines.`,
|
|
7928
|
+
suggestion: `Check the Billing Library version in your Gradle dependencies against Google's support timeline: ${DEPRECATION_FAQ}`,
|
|
7929
|
+
policyUrl: DEPRECATION_FAQ
|
|
7930
|
+
}
|
|
7931
|
+
];
|
|
7932
|
+
}
|
|
7933
|
+
const major = Number(majorMatch[0]);
|
|
7934
|
+
const status = billingLibraryStatus(major, now);
|
|
7935
|
+
if (!status) return [];
|
|
7936
|
+
const shipsVersion = `This bundle ships Google Play Billing Library ${version}.`;
|
|
7937
|
+
const advice = migrationAdvice(targetMajor(major, now));
|
|
7938
|
+
let title;
|
|
7939
|
+
let message;
|
|
7940
|
+
let suggestion = advice;
|
|
7941
|
+
if (status === "older-than-table") {
|
|
7942
|
+
const oldest = BILLING_LIBRARY_DEADLINES[OLDEST_KNOWN];
|
|
7943
|
+
title = `Google Play Billing Library ${major} is no longer supported`;
|
|
7944
|
+
message = `${shipsVersion} It is older than Billing Library ${OLDEST_KNOWN}, whose extension deadline passed on ${oldest?.extensionDeadline ?? "an earlier date"}. Google Play no longer accepts new apps or app updates built on it.`;
|
|
7945
|
+
} else {
|
|
7946
|
+
const deadlines = BILLING_LIBRARY_DEADLINES[major];
|
|
7947
|
+
if (!deadlines) return [];
|
|
7948
|
+
if (status === "past-extension-deadline") {
|
|
7949
|
+
title = `Google Play Billing Library ${major} is no longer supported`;
|
|
7950
|
+
message = `${shipsVersion} Its extension deadline passed on ${deadlines.extensionDeadline}, so Google Play no longer accepts new apps or app updates built on Billing Library ${major}.`;
|
|
7951
|
+
} else if (status === "past-update-deadline") {
|
|
7952
|
+
title = `Google Play Billing Library ${major} is past its update deadline`;
|
|
7953
|
+
message = `${shipsVersion} Its update deadline passed on ${deadlines.updateDeadline}. Until ${deadlines.extensionDeadline}, Google Play accepts new apps and app updates on Billing Library ${major} only if the app was granted an extension. After that date it accepts none.`;
|
|
7954
|
+
suggestion = `To keep shipping while you migrate, request an extension from the warning on Play Console's Policy status page. ${advice}`;
|
|
7955
|
+
} else {
|
|
7956
|
+
title = `Google Play Billing Library ${major} update deadline is ${deadlines.updateDeadline}`;
|
|
7957
|
+
message = `${shipsVersion} After ${deadlines.updateDeadline}, Google Play accepts new apps and app updates on Billing Library ${major} only with an extension, and after ${deadlines.extensionDeadline} not at all.`;
|
|
7958
|
+
}
|
|
7959
|
+
}
|
|
7960
|
+
return [
|
|
7961
|
+
{
|
|
7962
|
+
scanner: "policy",
|
|
7963
|
+
ruleId: "billing-library-deprecated",
|
|
7964
|
+
severity: STATUS_SEVERITY[status],
|
|
7965
|
+
title,
|
|
7966
|
+
message,
|
|
7967
|
+
suggestion,
|
|
7968
|
+
policyUrl: DEPRECATION_FAQ
|
|
7969
|
+
}
|
|
7970
|
+
];
|
|
7971
|
+
}
|
|
7972
|
+
|
|
7817
7973
|
// src/preflight/scanners/policy-scanner.ts
|
|
7818
7974
|
var policyScanner = {
|
|
7819
7975
|
name: "policy",
|
|
@@ -7912,6 +8068,18 @@ var policyScanner = {
|
|
|
7912
8068
|
policyUrl: "https://support.google.com/googleplay/android-developer/answer/13392821"
|
|
7913
8069
|
});
|
|
7914
8070
|
}
|
|
8071
|
+
if (perms.has("android.permission.ACCESS_LOCAL_NETWORK") && manifest.targetSdk >= 37) {
|
|
8072
|
+
findings.push({
|
|
8073
|
+
scanner: "policy",
|
|
8074
|
+
ruleId: "policy-local-network-declaration",
|
|
8075
|
+
severity: "info",
|
|
8076
|
+
title: "ACCESS_LOCAL_NETWORK requires a Play Console declaration",
|
|
8077
|
+
message: `This app targets API ${manifest.targetSdk} and requests ACCESS_LOCAL_NETWORK. From August 25, 2027, Google Play requires apps targeting Android 17 (API 37) or higher to submit a Play Console declaration to use this permission, and allows it only for core functionality that device pickers cannot provide. The declaration is stored in Play Console, so it cannot be verified from the AAB.`,
|
|
8078
|
+
suggestion: "If a device picker (for example NsdManager discovery through the system picker) covers your use case, use it and drop ACCESS_LOCAL_NETWORK. Otherwise submit the local network declaration in Play Console, explaining why device pickers are not sufficient.",
|
|
8079
|
+
policyUrl: "https://support.google.com/googleplay/android-developer/answer/16935362#local_network_permission"
|
|
8080
|
+
});
|
|
8081
|
+
}
|
|
8082
|
+
findings.push(...billingLibraryFindings(manifest, /* @__PURE__ */ new Date()));
|
|
7915
8083
|
if (perms.has("android.permission.SYSTEM_ALERT_WINDOW")) {
|
|
7916
8084
|
findings.push({
|
|
7917
8085
|
scanner: "policy",
|
|
@@ -10529,6 +10697,7 @@ export {
|
|
|
10529
10697
|
analyzeReviews2 as analyzeReviews,
|
|
10530
10698
|
annotateListResult,
|
|
10531
10699
|
applyReleaseNotes,
|
|
10700
|
+
applyVitalThresholds,
|
|
10532
10701
|
assertRateThreshold,
|
|
10533
10702
|
assignRelease,
|
|
10534
10703
|
batchGetOrders,
|